From 75848a2a6972a3de95dd8d0a52ff2cf0443adad7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 May 2016 11:35:52 -0700 Subject: [PATCH] Implement the `panic` profile option This is the Cargo half of the implementation of [RFC 1513] which adds a new `profile.*.panic` option to customize the `-C panic` argument to the compiler. This is not passed by default and can otherwise be specified as `abort` or `unwind` on the nightly compiler. [RFC 1513]: https://github.com/rust-lang/rfcs/pull/1513 The `profile.*.panic` option is *only* used from the top-level crate, not each crate individually. This means that applications should customize this value as they see fit, and libraries will only use their own value when they're being tested. Cargo also has specific knowledge that when *testing* a crate it can't pass `-C panic=abort` for now as the default test harness requires `panic=unwind`. This essentially just means that `cargo test` will continue to work for crates that specify `panic=abort` in Cargo.toml. --- src/cargo/core/manifest.rs | 4 ++++ src/cargo/ops/cargo_clean.rs | 6 +++-- src/cargo/ops/cargo_compile.rs | 1 + src/cargo/ops/cargo_rustc/context.rs | 11 +++++++--- src/cargo/ops/cargo_rustc/mod.rs | 7 +++++- src/cargo/util/toml.rs | 14 ++++++++++-- src/rustversion.txt | 2 +- tests/test_cargo_compile.rs | 20 +++++++++++++++++ tests/test_cargo_test.rs | 33 ++++++++++++++++++++++++++++ 9 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index a988460f6..00639978c 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -113,6 +113,7 @@ pub struct Profile { pub test: bool, pub doc: bool, pub run_custom_build: bool, + pub panic: Option, } #[derive(Default, Clone, Debug)] @@ -120,7 +121,9 @@ pub struct Profiles { pub release: Profile, pub dev: Profile, pub test: Profile, + pub test_deps: Profile, pub bench: Profile, + pub bench_deps: Profile, pub doc: Profile, pub custom_build: Profile, } @@ -469,6 +472,7 @@ impl Default for Profile { test: false, doc: false, run_custom_build: false, + panic: None, } } } diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index f5dfdb0d9..605607171 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -58,9 +58,11 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> { try!(rm_rf(&layout.build(&pkg))); let Profiles { ref release, ref dev, ref test, ref bench, ref doc, - ref custom_build, + ref custom_build, ref test_deps, ref bench_deps, } = *root.manifest().profiles(); - for profile in [release, dev, test, bench, doc, custom_build].iter() { + let profiles = [release, dev, test, bench, doc, custom_build, + test_deps, bench_deps]; + for profile in profiles.iter() { let unit = Unit { pkg: &pkg, target: target, diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index d330ea3ce..9ae3f007c 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -244,6 +244,7 @@ pub fn compile_pkg<'a>(root_package: &Package, let mut build_config = try!(scrape_build_config(config, jobs, target)); build_config.exec_engine = exec_engine.clone(); build_config.release = release; + build_config.test = mode == CompileMode::Test; if let CompileMode::Doc { deps } = mode { build_config.doc_all = deps; } diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 62f9e9818..0c914b406 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -620,10 +620,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } pub fn lib_profile(&self, _pkg: &PackageId) -> &'a Profile { - if self.build_config.release { - &self.profiles.release + let (normal, test) = if self.build_config.release { + (&self.profiles.release, &self.profiles.bench_deps) } else { - &self.profiles.dev + (&self.profiles.dev, &self.profiles.test_deps) + }; + if self.build_config.test { + test + } else { + normal } } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index ab1ce343e..c7c6e6252 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -40,6 +40,7 @@ pub struct BuildConfig { pub requested_target: Option, pub exec_engine: Option>>, pub release: bool, + pub test: bool, pub doc_all: bool, } @@ -451,7 +452,7 @@ fn build_base_args(cx: &Context, let Profile { opt_level, lto, codegen_units, ref rustc_args, debuginfo, debug_assertions, rpath, test, doc: _doc, run_custom_build, - rustdoc_args: _, + ref panic, rustdoc_args: _, } = *unit.profile; assert!(!run_custom_build); @@ -478,6 +479,10 @@ fn build_base_args(cx: &Context, cmd.arg("-C").arg(&format!("opt-level={}", opt_level)); } + if let Some(panic) = panic.as_ref() { + cmd.arg("-C").arg(format!("panic={}", panic)); + } + // Disable LTO for host builds as prefer_dynamic and it are mutually // exclusive. if unit.target.can_lto() && lto && !unit.target.for_host() { diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 5e0d3868e..82ea4533a 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -238,6 +238,7 @@ pub struct TomlProfile { debug: Option, debug_assertions: Option, rpath: Option, + panic: Option, } #[derive(RustcDecodable)] @@ -1030,23 +1031,31 @@ fn normalize(lib: &Option, fn build_profiles(profiles: &Option) -> Profiles { let profiles = profiles.as_ref(); - return Profiles { + let mut profiles = Profiles { release: merge(Profile::default_release(), profiles.and_then(|p| p.release.as_ref())), dev: merge(Profile::default_dev(), profiles.and_then(|p| p.dev.as_ref())), test: merge(Profile::default_test(), profiles.and_then(|p| p.test.as_ref())), + test_deps: merge(Profile::default_dev(), + profiles.and_then(|p| p.dev.as_ref())), bench: merge(Profile::default_bench(), profiles.and_then(|p| p.bench.as_ref())), + bench_deps: merge(Profile::default_release(), + profiles.and_then(|p| p.release.as_ref())), doc: merge(Profile::default_doc(), profiles.and_then(|p| p.doc.as_ref())), custom_build: Profile::default_custom_build(), }; + profiles.test_deps.panic = None; + profiles.bench_deps.panic = None; + return profiles; fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile { let &TomlProfile { - opt_level, lto, codegen_units, debug, debug_assertions, rpath + opt_level, lto, codegen_units, debug, debug_assertions, rpath, + ref panic } = match toml { Some(toml) => toml, None => return profile, @@ -1063,6 +1072,7 @@ fn build_profiles(profiles: &Option) -> Profiles { test: profile.test, doc: profile.doc, run_custom_build: profile.run_custom_build, + panic: panic.clone().or(profile.panic), } } } diff --git a/src/rustversion.txt b/src/rustversion.txt index f3e7aced5..1557cfb2f 100644 --- a/src/rustversion.txt +++ b/src/rustversion.txt @@ -1 +1 @@ -2016-04-23 +2016-05-13 diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 58246eb04..46772789a 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -2128,3 +2128,23 @@ test!(manifest_with_bom_is_ok { assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0)); }); + +test!(panic_abort_compiles_with_panic_abort { + if !::is_nightly() { + return + } + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [profile.dev] + panic = 'abort' + "#) + .file("src/lib.rs", ""); + assert_that(p.cargo_process("build").arg("-v"), + execs().with_status(0) + .with_stderr_contains("[..] -C panic=abort [..]")); +}); diff --git a/tests/test_cargo_test.rs b/tests/test_cargo_test.rs index 7d0493e3b..1145f91f3 100644 --- a/tests/test_cargo_test.rs +++ b/tests/test_cargo_test.rs @@ -2072,3 +2072,36 @@ test result: ok.[..] ")); }); +test!(test_panic_abort_with_dep { + if !::is_nightly() { + return + } + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = { path = "bar" } + + [profile.dev] + panic = 'abort' + "#) + .file("src/lib.rs", r#" + extern crate bar; + + #[test] + fn foo() {} + "#) + .file("bar/Cargo.toml", r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + "#) + .file("bar/src/lib.rs", ""); + assert_that(p.cargo_process("test").arg("-v"), + execs().with_status(0)); +}); -- 2.30.2